package cn.gogpay.dcb.api.service;

import cn.gogpay.dcb.api.common.constant.BizConstant;
import cn.gogpay.dcb.api.dao.OrderRecordRepository;
import cn.gogpay.dcb.api.dto.qrcode.QrCodeChargeDTO;
import cn.gogpay.dcb.api.entity.GoodsItem;
import cn.gogpay.dcb.api.entity.OrderRecord;
import cn.gogpay.dcb.api.entity.UserBusCard;
import cn.gogpay.dcb.api.feign.ApiPlatformClient;
import cn.gogpay.dcb.api.web.ApiController;
import cn.gogpay.dcb.common.dto.ResultCode;
import cn.gogpay.dcb.common.dto.ResultDTO;
import cn.gogpay.dcb.common.service.BaseService;
import cn.gogpay.dcb.h5base.dto.UserDTO;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author jiaoming@gogpay.cn
 * @date 2019/12/2 23:03
 */
@Service
public class RechargeRecordService extends BaseService<OrderRecord, String> {
    private static final Logger logger = LoggerFactory.getLogger(RechargeRecordService.class);

    @Value("${spring.profiles.active}")
    private String dev;
    @Autowired
    private OrderRecordRepository recordRepository;
    @Autowired
    private ApiPlatformClient apiPlatformClient;
    @Autowired
    private UserBusCardService userBusCardService;
    @Autowired
    private  RabbitTemplate rabbitTemplate;

    @Override
    protected JpaRepository<OrderRecord, String> getBaseRepository() {
        return recordRepository;
    }


    public OrderRecord createThirdOrder(UserDTO userDTO, GoodsItem goodsItem) {
        OrderRecord record = new OrderRecord();

        UserBusCard userBusCard = userBusCardService.findByUserId(userDTO.getUserId());
        record.setStatus("0");
        record.setPrice(goodsItem.getPrice());
        record.setCardNo(userBusCard.getCardNo());
        record.setGoodsItemId(goodsItem.getId());
        record.setPhone(userDTO.getPhoneNo());
        record.setUserId(userDTO.getUserId());
        record = saveAndFlush(record);
        logger.info("record:{}", JSONObject.toJSONString(record));

        return record;
    }

    public OrderRecord updateOrder(OrderRecord record) {
        if ("2".equals(record.getStatus())){
            logger.info("已销帐，请不要重复处理");
            writeOff(record.getOrderNo());
        }else {
            QrCodeChargeDTO qrCodeChargeDTO = new QrCodeChargeDTO(record);
            ResultDTO resultDTO = apiPlatformClient.qrCodeRecharge(qrCodeChargeDTO);
            logger.info("公交销帐结果:{}",JSONObject.toJSONString(resultDTO));
            if (resultDTO.isSuccess()) {
                /**
                 * {
                 *  "code": "200",
                 *  "msg": "请求成功",
                 *  "result": {
                 *  "userPhone": "13756105820",
                 *  "cardNo": "3105072000680000001",
                 *  "accountNo": "",
                 *  "balance": "50.00",
                 *  },
                 *  "success": true
                 * }
                 */
                JSONObject originalResult = (JSONObject) resultDTO.getData();
                if ("200".equals(originalResult.getString("code"))) {
                    JSONObject result = originalResult.getJSONObject("result");
                    String balance = result.getString("balance");
                    record.setStatus("2");
                    record.setBalance(balance);
                    record = save(record);
                    writeOff(record.getOrderNo());
                }
            }
        }
        return record;
    }

    private void writeOff(String orderNo){
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("status", BizConstant.WriteOffStatus.WRITE_OFF_STATUS_SUCCESS);
        jsonObject.put("orderNo", orderNo);
        jsonObject.put("statusTime", System.currentTimeMillis());
        rabbitTemplate.convertAndSend("EdgeServiceToOrderCenterUpdateWriteOffStatus", jsonObject.toString());
    }

    public ResultDTO getOrderParams(OrderRecord record) {
        //测试金额
        String price = record.getPrice() + "";
        if ("dev".equals(dev)) {
            price = "0.01";
        }
        ResultDTO resultDTO = new ResultDTO(ResultCode.tradeSuccess());
        Map<String, Object> order = new HashMap<>();
        order.put("recordId", record.getId());
        order.put("amt", price);
        order.put("receivable", price);
        order.put("type", BizConstant.TYPE);
        order.put("orgCode", BizConstant.ORGCODE);
        order.put("areaCode", BizConstant.AREACODE);
        order.put("unitOrgCode", BizConstant.UNITORGCODE);
        order.put("unitOrgName", BizConstant.UNITORGNAME);
        order.put("consNo", record.getCardNo());
        order.put("payAmt", price);
        resultDTO.setMsg("创建成功");
        resultDTO.setData(order);
        return resultDTO;
    }

    public OrderRecord findByOrderNo(String orderNo) {
        OrderRecord query = new OrderRecord();
        query.setOrderNo(orderNo);

        Example<OrderRecord> example=Example.of(query);
        return recordRepository.findOne(example).orElse(null);
    }

    public List<OrderRecord> findByUserId(String userId) {
        OrderRecord query = new OrderRecord();
        query.setUserId(userId);
        query.setPayStatus("01");
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");

        Example<OrderRecord> example=Example.of(query);
        return recordRepository.findAll(example,sort);
    }

    public OrderRecord findByCardNo(String cardNo) throws Exception{
        OrderRecord query = new OrderRecord();
        query.setCardNo(cardNo);
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");

        Example<OrderRecord> example=Example.of(query);
        List<OrderRecord> list = recordRepository.findAll(example,sort);
        for (OrderRecord record:list){
            if (!StringUtils.isEmpty(record.getPhone())){
                return record;
            }
        }
       return null;
    }
}
